package kiwi.uima.enhancer;

import java.io.IOException;
import java.net.URL;
import java.util.Iterator;

import kiwi.core.exception.KiWiException;
import kiwi.core.model.content.MediaContentItem;
import kiwi.core.model.rdf.KiWiMediaContentLiteral;
import kiwi.core.model.rdf.KiWiResource;
import kiwi.enhancer.ContentEnhancer;
import kiwi.media.Annotation;

import org.apache.uima.UIMAFramework;
import org.apache.uima.analysis_engine.AnalysisEngine;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceSpecifier;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;
/**
 * <p>Simple UIMA Enhancer class<p>
 * <p>The UIMA Enhancer implements the {@link ContentEnhancer} interface
 * therefore it will be called whenever an appropriate event is 
 * thrown</p>
 * 
 * @author dglachs
 *
 */
public class UimaEnhancer implements ContentEnhancer {

	private ResourceSpecifier spec;
	
	@Override
	public void enhance(MediaContentItem contentItem) throws KiWiException {
        if(contentItem == null){
            throw new IllegalArgumentException("The parsed Content Item MUST NOT be NULL!");
        }
        KiWiResource resource = contentItem.getDelegate();
        if(resource == null){
            throw new IllegalStateException(String.format("Delegate for MediaContentItem %s is NULL!",contentItem));
        }
        if(resource.isLiteral()){
            throw new IllegalStateException(String.format("Delegate of MediaContentItem %s is of type Literal (value=%s)",
                contentItem,resource));
        } //else we can use it
        KiWiMediaContentLiteral content = contentItem.getMediaContent();
        if(content == null){
            throw new IllegalStateException(String.format("Content (KiWiMediaContentLiteral) for MediaContentItem %s is NULL!",
                contentItem));
        }
        // call uima - however still no glue what to do with the results, since there are not triples
        // 
        callUIMA(content.getContent());

	}
	/**
	 * <p>Helper Method to produce the analysis engine which is then provided with a
	 * simple {@link CAS}</p>
	 * @param textContent
	 * @throws KiWiException
	 */
	private void callUIMA(String textContent) throws KiWiException {
		try {
			// obtain an analysis engine
			AnalysisEngine engine = UIMAFramework.produceAnalysisEngine(getSpecifier());
			// initialize the Common Analysis Structure (CAS)
			CAS aCas =  engine.newCAS();
			// use the string representation of the mediacontent item 
			aCas.setDocumentText(textContent) ;
			// process the media content item with uima
			engine.process(aCas);
			// TODO provide useful consumer
		    Iterator<AnnotationFS> it = aCas.getAnnotationIndex().iterator();
		    if (it.hasNext()) {
		    	Object obj = it.next();
		    	if ( obj instanceof Annotation) {
		    		Annotation srcDocInfo = (Annotation) obj;
		    		String docUri = srcDocInfo.getAnnotator();
		    		System.out.println(docUri);
		    		System.out.println(srcDocInfo.getEnd());
		    	}
		    }

			// consume the results
			// UIMAFramework.produceCasConsumer()
			
		} catch (ResourceInitializationException e) {
			// TODO Auto-generated catch block
			throw new KiWiException("The requested annotation descriptor could not be initialized ");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			throw new KiWiException("IO Exception occurred");
		} catch (AnalysisEngineProcessException e) {
			// TODO Auto-generated catch block
			throw new KiWiException("Analysis Processing failed");
		}
	}
	
	/**
	 * Helper method to obtain a AE specifier
	 * @return
	 * @throws IOException
	 */
	private ResourceSpecifier getSpecifier() throws IOException {
		if ( spec == null ) {
			// TODO:  specifiy how to obtain the specification - this is just a workaround
			URL url = this.getClass().getResource("/sampleAnalysisEngine.xml");

			XMLInputSource in = new XMLInputSource(url);
	        try {
				spec = UIMAFramework.getXMLParser().parseResourceSpecifier(in);
			} catch (InvalidXMLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		return spec;
	}
}
